﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Text;


namespace SharePointClient
{
    public class DocumentCollection:IDisposable,IEnumerable<Document>
    {
        
        private List list;
        private List<Document> documents;

        public DocumentCollection(List list)
        {
            this.list = list;
            documents = new List<Document>();
            Refresh();
        }
        public Document Upload(string localfilename)
        {
            string dest =  System.IO.Path.GetFileName(localfilename);
            if (list.RootFolder.EndsWith("/")) dest = list.RootFolder + dest;
            else dest = list.RootFolder + "/" + dest;

            if (list.Connection.Upload(localfilename, new Uri(dest)))
                return Refresh(System.IO.Path.GetFileName(localfilename));
            else
            {
                return null;
            }
        }
        public Document Refresh(string filename)
        {
            XmlDocument doc = new XmlDocument();
            XmlDocument qry = new XmlDocument();
            qry.LoadXml("<Query><Where><Eq><FieldRef Name=\"FileLeafRef\" \\><Value Type=\"File\">" + filename + "</Value></Lt></Where></Query>");
            
            doc.LoadXml("<ViewFields>" +
                "<FieldRef Name=\"ID\" />" +
                "<FieldRef Name=\"Title\" />" +
                "<FieldRef Name=\"FileLeafRef\" />" +
                "<FieldRef Name=\"FileRef\" />" +
                "<FieldRef Name=\"Created\" />" +
                "<FieldRef Name=\"Author\" />" +
                "<FieldRef Name=\"Modified\" />" +
                "<FieldRef Name=\"Editor\" />" +
                "</ViewFields>");
            ProgressEventArgs p = list.Connection.DoProgress("Refresh Document '"+filename+"' from '" + list.Title + "'");
            XmlNode data = list.GetData(qry.FirstChild, doc.FirstChild, 1000);
            documents.Clear();
            Document ret = null;
            foreach (XmlNode n in WSSBase.Select(data, "/rs:data/z:row"))
            {
                Document ldoc = new Document(list, n);
                if (Contains(ldoc.ID))
                {
                    documents[ldoc.ID].Update(list, n);
                    ret = documents[ldoc.ID];
                    ldoc.Dispose();
                }
                else
                {
                    documents.Add(ldoc);
                    ret = ldoc;
                }
            }
            p.Operation = "One Document refreshed.";
            p.State = BeforeOrAfter.After;
            list.Connection.UpdateProgress(p);
            return ret;
        }

        public void Refresh()
        {
            XmlDocument doc = new XmlDocument();

            doc.LoadXml("<ViewFields>" +
                "<FieldRef Name=\"ID\" />" +
                "<FieldRef Name=\"Title\" />" +
                "<FieldRef Name=\"FileLeafRef\" />" +
                "<FieldRef Name=\"FileRef\" />" +
                "<FieldRef Name=\"Created\" />" +
                "<FieldRef Name=\"Author\" />" +
                "<FieldRef Name=\"Modified\" />" +
                "<FieldRef Name=\"Editor\" />" +
                "</ViewFields>");
            ProgressEventArgs p = list.Connection.DoProgress("Loading Documents from '" + list.Title + "'");
            XmlNode data=list.GetData(null,doc.FirstChild,1000);
            documents.Clear();
            foreach (XmlNode n in WSSBase.Select(data, "/rs:data/z:row"))
            {
                Document ldoc = new Document(list, n);

                documents.Add(ldoc);
            }
            p.Operation = "Document loaded from List '" + list.Title + "'.";
            p.State = BeforeOrAfter.After;
            list.Connection.UpdateProgress(p);
        }
        public bool Contains(int id)
        {
            foreach (Document doc in documents) if (doc.ID == id) return true; return false; 
        }

        /// <summary>
        /// Returns the Document with special ID
        /// </summary>
        /// <param name="id">The sharepoint-listitem-id</param>
        /// <returns>Document</returns>
        /// <remarks>Attention: This id is not the same as the position. If a document is deleted from SharePointList its id is spared</remarks>
        public Document this[int id]
        {
            get { foreach (Document doc in documents) if (doc.ID == id) return doc; return null; }
        }
        /// <summary>
        /// Get a Document by filename
        /// </summary>
        /// <param name="filename">search for filename</param>
        /// <returns>Document</returns>
        public Document this[string filename]
        {
            get { filename = filename.ToLower(); foreach (Document doc in documents) if (doc.Filename.ToLower() == filename) return doc; return null; }
        }
        

        #region IDisposable Member

        public void Dispose()
        {
            documents.Clear();
        }

        #endregion

        #region IEnumerable<Document> Member

        public IEnumerator<Document> GetEnumerator()
        {
            return documents.GetEnumerator();
        }

        #endregion

        #region IEnumerable Member

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return documents.GetEnumerator();
        }

        #endregion
    }
}
